// @ts-nocheck
import fs from 'node:fs';
import path from 'node:path';
import { nanoid } from 'nanoid';
import { config } from '@e/config';
import { download } from '../download';
import { ColorScheme } from '@p/utils';
import { __path } from '@e/methods/path';
import { BrowserWindow } from 'electron';
import { downloadImage } from '../downloadImage';
import { readMdFile } from '@e/createWindow/WindowService/readMdFile';
import { getURLFilename } from '@e/methods/getURLFilename';
import { escapeRegExp, escapeHTML } from '@e/methods/escape';
import { getImageCitationInfo } from '../getImageCitationInfo';
import { errorDialog, fileAlreadyExistDialog } from '@e/dialog';
import { Mode1Data, Mode2Data, Mode3Data, Mode3Data_savePath, Mode4Data, Mode6Data } from '@p/main-modeData';
import {
	isInlineImageReferenceRegExp,
	matchInlineImageReferencePathRegExp,
	matchTagImageReferencePathRegExp,
	matchInlineImageReference2PartsRegExp,
	matchInlineImageReference3PartsRegExp,
	matchTagImageReference2PartsRegExp,
	matchTagImageReference3PartsRegExp,
	isUrlRegExp,
	getMarkdownImageReferenceRegExp,
} from '@e/utils/regexp';
import {
	MdFileInfo,
	ImageDirInfo,
	DownloadInfo,
	ReplaceConfig,
	MoveFileConfig,
	MoveFileResult,
	MessageObject1,
	MessageObject2,
	FileAlreadyExistResponse,
	LoadImageData,
	LoadImageDataValue,
	State_work_currentMode,
	State,
	ReplaceInfo,
} from '@p/main-windowObject';

interface Event {
	load: Function[];
}

interface FormatSavePathResult {
	moveList: MoveFileConfig[];
	replaceList: ReplaceConfig[];
}

export class WindowService {
	constructor(win: BrowserWindow, id: number, filePath?: string, state?: Object) {
		this.window = win;
		this.id = id;
		if (filePath) this.filePath = filePath;
		if (state) this.state = { ...this.state, ...state };
	}

	/**
	 * 窗口对象
	 */
	window: BrowserWindow;

	/**
	 * 窗口id
	 */
	id: number;

	/**
	 * 文件路径
	 */
	filePath?: string;

	/**
	 * 文件信息
	 */
	fileInfo?: MdFileInfo;

	/**
	 * 加载图片信息
	 */
	loadImageData: LoadImageData = {};

	state: State = {
		colorScheme: 'dark',
		work: {
			ongoing: false,
			currentMode: null,
		},
	};

	/**
	 * 颜色
	 */
	colors = {
		dark: {
			backgroundColor: '#262727',
		},
		light: {
			backgroundColor: '#ededed',
		},
	};

	/**
	 * 事件列表
	 */
	event: Event = {
		load: [],
	};

	/**
	 * 当前消息 id
	 */
	messageID: number = -1;

	/**
	 * 添加加载完毕回调执行函数
	 */
	onload(fn: Function) {
		this.event.load.push(fn);
	}

	/**
	 * 获取文件信息
	 */
	getFileInfo(_path?: string, bool: boolean = true): Promise<[MdFileInfo, number]> {
		if (_path) this.filePath = _path;

		return new Promise((resolve, reject) => {
			let messageId = -1;

			if (bool) {
				messageId = this.sendMessage().insert({ type: 'info', message: `正在读取文件 "${this.filePath}"` });
			}

			readMdFile(this.filePath as string).then(
				(data) => {
					this.fileInfo = data;
					resolve([data, messageId]);
				},
				(e) => {
					reject();
					errorDialog('文件读取失败', e.message + `\npath: "${_path}"`);
				}
			);
		});
	}

	/**
	 * 向渲染进程发送数据
	 */
	send(channel: string, ...args: any[]) {
		this.window.webContents.send(channel, ...args);
	}

	/**
	 * 向页面发送消息
	 */
	sendMessage() {
		const thia = this;

		return {
			insert(obj: MessageObject1) {
				thia.messageID++;

				thia.send('message', 'insert', { ...obj, id: thia.messageID });

				return thia.messageID;
			},
			update(obj: MessageObject2) {
				thia.send('message', 'update', obj);
			},
		};
	}

	/**
	 * 加载图片
	 */
	loadImage(url: string): Promise<string | undefined> {
		return new Promise((resolve) => {
			if (this.loadImageData[url] && this.loadImageData[url].result) {
				resolve(this.loadImageData[url].base64URL as string);
			} else {
				let obj: LoadImageDataValue = {
					result: true,
				};

				downloadImage(url)
					.then(
						(res) => {
							obj = { ...obj, ...res };
							resolve(res.base64URL as string);
						},
						() => {
							obj.result = false;
							resolve(undefined);
						}
					)
					.finally(() => {
						this.loadImageData[url] = obj;
					});
			}
		});
	}

	/**
	 * 获取写入的旧文件的文件路径
	 */
	getOldFilePath(dirPath: string, filename: string) {
		const name = filename.split('.')[0];
		let i = 1;
		let _filename = name + '-old.md';
		let filePath = path.join(dirPath, _filename);

		if (!/-old(\([0-9]+\))?\.md/.test(filename)) {
			if (!__path.check.exist(filePath)) return filePath;
		}

		while (true) {
			_filename = name + `(${i}).md`;

			filePath = path.join(dirPath, _filename);

			if (!__path.check.exist(filePath)) return filePath;

			// 不能超过999
			if (i++ > 999) return filePath;
		}
	}

	/**
	 * 写入旧文件
	 */
	writeOldFile(callback: Function) {
		if (config.configFile.base.generateOldFile) {
			const fileInfo = this.fileInfo as MdFileInfo;
			const oldFilePath = this.getOldFilePath(fileInfo.dirPath, fileInfo.fileName);

			fs.writeFile(oldFilePath, fileInfo.content, (err) => {
				if (err) {
					callback(err);
					return errorDialog('旧文件写入失败', err.message);
				} else {
					callback();
				}
			});
		} else {
			callback();
		}
	}

	/**
	 * 写入文件
	 * @param s 是否写入旧文件
	 */
	writeFile(content: string, callback?: Function, s?: boolean) {
		function complete() {
			if (callback) callback();
		}

		fs.writeFile(this.filePath as string, content, (err) => {
			if (err) {
				return errorDialog('写入文件失败', err.message);
			}

			if (s) {
				complete();
			} else {
				this.writeOldFile(() => {
					complete();
				});
			}
		});
	}

	/**
	 * 获取图片的目录信息
	 */
	getImageDirInfo(): ImageDirInfo[] {
		const fileInfo = this.fileInfo as MdFileInfo;
		const arr: ImageDirInfo[] = [];

		return fileInfo.imageInfo.reduce((t, item) => {
			if (item.type === 'relative' || item.type === 'absolute') {
				let filePath = item.absolute as string;

				const result = __path.check.file(filePath);

				if (result === 'ok' && !item.exist) {
					let fileDir = path.dirname(filePath);

					const i = arr.find((s) => s.dirPaht === fileDir);

					if (i) {
						i.images.push(item);
					} else {
						t.push({
							dirPaht: fileDir,
							images: [item],
						});
					}
				}
			}

			return t;
		}, arr);
	}

	/**
	 * 设置颜色方案
	 */
	setColorScheme(s: ColorScheme) {
		this.state.colorScheme = s;

		if (s === 'dark') {
			this.window.setBackgroundColor(this.colors.dark.backgroundColor);
		} else {
			this.window.setBackgroundColor(this.colors.light.backgroundColor);
		}
	}

	/**
	 * 生成下载信息
	 */
	generateDownloadInfo(obj: Mode1Data): DownloadInfo[] {
		const thia = this;

		// 没有文件名的处理
		function notFilename(obj: DownloadInfo): DownloadInfo {
			obj.filename = nanoid();
			obj.notExt = true;

			return obj;
		}

		// 统一保存处理
		function unifiedSaveFn(): DownloadInfo[] {
			return (thia.fileInfo as MdFileInfo).imageInfo
				.filter((i) => i.type === 'url')
				.map((item) => {
					let infoItem: DownloadInfo = {
						url: item.target,
						savePath: obj.unifiedSavePath,
						filename: getURLFilename(item.target),
					};

					if (!infoItem.filename) {
						// 如果没能从url中提取到文件名的处理
						infoItem = notFilename(infoItem);
					}

					return infoItem;
				});
		}

		// 分别保存处理
		function separatelySaveFn() {
			const zarr: DownloadInfo[] = [];

			return obj.separatelySavePaths.reduce((t, item) => {
				const arr = item.children.map((s_item) => {
					let infoItem: DownloadInfo = {
						url: s_item.target,
						savePath: item.dirPaht,
						filename: getURLFilename(s_item.target),
					};

					if (!infoItem.filename) {
						// 如果没能从url中提取到文件名的处理
						infoItem = notFilename(infoItem);
					}

					return infoItem;
				});

				t.push(...arr);

				return t;
			}, zarr);
		}

		switch (obj.saveMode) {
			case 'unifiedSave':
				return unifiedSaveFn();
			case 'separatelySave':
				return separatelySaveFn();
		}
	}

	/**
	 * 移动文件
	 */
	moveFile(arr: MoveFileConfig[]): Promise<MoveFileResult[]> {
		return new Promise((resolve) => {
			const thia = this;
			let response: FileAlreadyExistResponse | null = null;
			let index = 0;

			function next() {
				index++;

				if (index < arr.length) {
					fn(arr[index]);
				} else {
					resolve(arr);
				}
			}

			/**
			 * 移动文件
			 */
			function move(obj: MoveFileResult) {
				if (obj.mode === 'copy') {
					// 复制文件
					fs.copyFile(obj.target, obj.movePosition, (err) => {
						if (err) {
							obj.result = false;
							errorDialog('错误', err.message);
						}
						next();
					});
				} else {
					// 移动文件
					fs.rename(obj.target, obj.movePosition, (err) => {
						if (err) {
							obj.result = false;
							errorDialog('错误', err.message);
						}

						next();
					});
				}
			}

			function fn(obj: MoveFileResult) {
				obj.result = true;

				const res = __path.check.file(obj.movePosition);

				if (res === 'ok' || res === 'not read') {
					let filename = path.basename(obj.movePosition);
					const fileDir = path.dirname(obj.movePosition);
					const name = filename.split('.')[0];
					const ext = filename.split('.')[1];

					// 验证加序号的文件名
					function AddNumber() {
						let i = 1;

						while (true) {
							const m = `${name}(${i}).${ext}`;

							const filePath = path.join(fileDir, m);

							if (!__path.check.exist(filePath)) return m;

							// 不能超过999
							if (i++ > 999) return m;
						}
					}

					// 文件已存在的结果处理
					function responseFn(str: FileAlreadyExistResponse) {
						switch (str) {
							case 'addNumber':
								obj.movePosition = path.join(fileDir, AddNumber());
								move(obj);
								break;
							case 'cover':
								move(obj);
								break;
							case 'cancel':
								obj.result = false;
								next();
								break;
						}
					}

					// 选择记住的处理
					if (response) {
						responseFn(response);
					} else {
						fileAlreadyExistDialog(thia.window, filename).then((s) => {
							if (s.learn) response = s.response;

							responseFn(s.response);
						});
					}
				} else {
					move(obj);
				}
			}

			fn(arr[0]);
		});
	}

	/**
	 * 关闭当前文档
	 */
	closeCurrentDocument() {
		this.filePath = undefined;
		this.fileInfo = undefined;
	}

	/**
	 * 设置工作状态
	 */
	setState_work(s1: boolean, s2: State_work_currentMode) {
		this.state.work.ongoing = s1;
		this.state.work.currentMode = s2;
	}

	/**
	 * 工作完成
	 */
	workCompleted(s = false, r = true) {
		this.setState_work(false, null);

		this.send('work-completed');

		this.sendMessage().insert({
			type: 'success',
			message: '操作完成',
		});

		if (r) {
			this.getFileInfo(undefined, s).then((arr) => {
				this.send('set-fileInfo', arr);
			});
		}
	}

	/**
	 * 格式化保存路径
	 */
	formatSavePath(
		arr: Mode3Data_savePath[],
		moveType: 'cut' | 'copy',
		replaceType: 'original' | 'relative' | 'absolute'
	): FormatSavePathResult {
		const result: FormatSavePathResult = {
			moveList: [],
			replaceList: [],
		};
		let index = 0;

		return arr.reduce((t, item) => {
			item.children.forEach((item2) => {
				const movePosition = path.join(item.dirPaht, item2.imageInfo.filename as string);

				t.moveList.push({
					id: index,
					target: path.join(item2.dirPaht, item2.imageInfo.filename as string),
					movePosition,
					mode: moveType,
				});

				let substituted = movePosition;

				const s1 = replaceType === 'original' && item2.imageInfo.type === 'relative';
				const s2 = replaceType === 'relative';

				if (s1 || s2) {
					substituted = path.relative((this.fileInfo as MdFileInfo).dirPath, substituted).replace(/\\/g, '/');
				}

				t.replaceList.push({
					id: index,
					target: item2.imageInfo.target,
					substituted,
				});

				index++;
			});

			return t;
		}, result);
	}

	/**
	 * 获取匹配 Markdown 文档的图片的正则字符串
	 */
	getMdImageRegStr(str: string) {
		return `(\\!\\[.*\\]\\(\.\*${str}\.\*\\)|\\<img(.*|\\s)src="\.\*${str}\.\*"(.*|\\s)\\/\\>)`;
	}

	/**
	 * 替换
	 */
	replace(arr: ReplaceConfig[]) {
		let value = (this.fileInfo as MdFileInfo).content;
		const mode = this.state.work.currentMode;

		arr.forEach((item) => {
			const str = escapeRegExp(item.target);

			let substituted = item.substituted;

			function mode1Fn() {}

			function mode2Fn(match: string, s: boolean) {
				if (!item.directReplace) {
					let m;
					if (s) {
						const matchs = match.match(matchInlineImageReferencePathRegExp);
						if (matchs && matchs[1]) {
							m = matchs[1];
						}
					} else {
						const matchs = match.match(matchTagImageReferencePathRegExp);
						if (matchs && matchs[1]) {
							m = matchs[1];
						}
					}

					if (m) {
						if (isUrlRegExp.test(m)) {
							substituted = m;
						} else {
							substituted = m.replace(item.target, item.substituted);
						}
					}
				}
			}

			function mode3Fn() {}

			function mode4Fn() {}

			function modeFn(match: string, s: boolean) {
				switch (mode) {
					case 'mode1':
						mode1Fn();
						break;
					case 'mode2':
						mode2Fn(match, s);
						break;
					case 'mode3':
						mode3Fn();
						break;
					case 'mode4':
						mode4Fn();
						break;
				}
			}

			const reg = getMarkdownImageReferenceRegExp(str);

			// 匹配出所有的图片引用
			value = value.replace(reg, (match) => {
				if (isInlineImageReferenceRegExp.test(match)) {
					// ![]() 引用处理
					modeFn(match, true);

					return match.replace(matchInlineImageReference2PartsRegExp, `$1${substituted}$2`);
				} else {
					// <img /> 引用处理
					modeFn(match, false);

					return match.replace(matchTagImageReference2PartsRegExp, `$1${substituted}$2`);
				}
			});
		});

		return value;
	}

	/**
	 * 查询替换信息
	 */
	queryReplaceInfo(arr: ReplaceConfig[], needed = ['absolute', 'relative']) {
		const value = (this.fileInfo as MdFileInfo).content;
		const thia = this;

		const info: ReplaceInfo[] = [];

		arr.forEach((item) => {
			const str = escapeRegExp(item.target);

			const reg = getMarkdownImageReferenceRegExp(str);

			function fn(str: string, arr: string[]) {
				const s = (thia.fileInfo as MdFileInfo).imageInfo.some((item) => {
					return item.target === arr[2] && needed.some((t) => item.type === t);
				});

				if (s) {
					const _reg = new RegExp(str);

					const _new = arr[2].replace(_reg, () => {
						return `<span class="mark">${item.substituted}</span>`;
					});

					const _old = arr[2].replace(_reg, (match) => {
						return `<span class="mark">${match}</span>`;
					});

					info.push({
						new: escapeHTML(arr[1]) + _new + escapeHTML(arr[3]),
						old: escapeHTML(arr[1]) + _old + escapeHTML(arr[3]),
						target: arr[2],
						substituted: arr[2].replace(_reg, item.substituted),
					});
				}
			}

			const match = value.match(reg);

			if (match) {
				match.forEach((item2) => {
					if (isInlineImageReferenceRegExp.test(item2)) {
						const matchs = item2.match(matchInlineImageReference3PartsRegExp);
						if (matchs) fn(str, matchs);
					} else {
						const matchs = item2.match(matchTagImageReference3PartsRegExp);
						if (matchs) fn(str, matchs);
					}
				});
			}
		});

		return info;
	}

	/**
	 * 获取图片引用关系
	 */
	getImageCitationInfo = getImageCitationInfo;

	/**
	 * 模式1处理函数
	 */
	mode1Fn(obj: Mode1Data) {
		if (this.state.work.ongoing) return;

		this.setState_work(true, 'mode1');

		const downloadInfo = this.generateDownloadInfo(obj);

		download(downloadInfo, this.sendMessage.bind(this), this.loadImageData).then((results) => {
			const arr = results
				.filter((i) => i.result)
				.map((item) => {
					let substituted = path.join(item.savePath, item.filename as string);

					if (obj.pathType === 'relative') {
						substituted = path.relative((this.fileInfo as MdFileInfo).dirPath, substituted);

						substituted = substituted.replace(/\\/g, '/');
					}

					return {
						target: item.url,
						substituted,
					};
				});

			const newContent = this.replace(arr);

			this.writeFile(newContent, () => {
				this.workCompleted();
			});
		});
	}

	// 模式2处理函数
	mode2Fn(obj: Mode2Data) {
		if (this.state.work.ongoing) return;

		this.setState_work(true, 'mode2');

		const replaceList: ReplaceConfig[] = obj.replaceList;

		if (obj.directReplace) {
			replaceList.forEach((_t, i) => {
				replaceList[i].directReplace = true;
			});
		}

		const newContent = this.replace(replaceList);

		this.writeFile(newContent, () => {
			this.workCompleted();
		});
	}

	/**
	 * 模式3处理函数
	 */
	mode3Fn(obj: Mode3Data) {
		if (this.state.work.ongoing) return;

		this.setState_work(true, 'mode3');

		const _config = this.formatSavePath(obj.savePath, obj.imageMovementMethod, obj.pathType);

		this.moveFile(_config.moveList).then((arr) => {
			const replaceList = _config.replaceList.filter((_item, i) => arr[i].result);

			const newContent = this.replace(replaceList);

			this.writeFile(newContent, () => {
				this.workCompleted();
			});
		});
	}

	/**
	 * 模式4处理函数
	 */
	mode4Fn(obj: Mode4Data) {
		if (this.state.work.ongoing) return;

		this.setState_work(true, 'mode3');

		const newPath = path.join(obj.newPath, path.basename(this.filePath as string));

		// 移动文件列表
		let moveList: MoveFileConfig[] = [
			{
				target: this.filePath as string,
				movePosition: newPath,
				mode: obj.fileMovementMethod,
			},
		];
		// 替换列表
		let replaceList: ReplaceConfig[] = [];

		if (obj.imageMovement) {
			const { moveList: _moveList, replaceList: _replaceList } = this.formatSavePath(
				obj.savePath,
				obj.imageMovementMethod,
				obj.imagePathType
			);

			moveList.push(..._moveList);

			replaceList = _replaceList;
		}

		this.moveFile(moveList).then((arr) => {
			if (arr[0].result) {
				this.filePath = newPath;

				if (obj.imageMovement) {
					replaceList = replaceList.filter((item) => arr.some((t) => item.id === t.id && t.result));

					const a = (this.fileInfo as MdFileInfo).imageInfo
						.filter((t) => t.type === 'relative' && !replaceList.some((n) => n.target === t.target))
						.map((item) => {
							return {
								target: item.target,
								substituted: path
									.relative(path.dirname(newPath), item.absolute as string)
									.replace(/\\/g, '/'),
							};
						});

					replaceList.push(...a);
				} else {
					replaceList = (this.fileInfo as MdFileInfo).imageInfo
						.filter((t) => t.type === 'relative')
						.map((item) => {
							return {
								target: item.target,
								substituted: path
									.relative(path.dirname(newPath), item.absolute as string)
									.replace(/\\/g, '/'),
							};
						});
				}

				const newContent = this.replace(replaceList);

				this.writeFile(
					newContent,
					() => {
						this.workCompleted();
					},
					false
				);
			}
		});
	}

	/**
	 * 模式6处理函数
	 */
	mode6Fn(obj: Mode6Data) {
		if (this.state.work.ongoing) return;
		this.setState_work(true, 'mode6');

		const buildDirName = 'build'; // 输出文件名称
		const imagesDirName = 'images'; // 存在图片文件夹名称
		const replaceList: ReplaceConfig[] = []; // 替换信息
		const moveList: MoveFileConfig[] = []; // 移动文件信息
		const downloadInfo: DownloadInfo[] = []; // 下载信息

		if (obj.outputSingleFile) {
			const p = path.join(obj.outputPath, buildDirName + '-' + (this.fileInfo as MdFileInfo).fileName);
			const createfilePath = __path.addNumber(p, 'file') as string;
			if (!createfilePath) return;

			const end = () => {
				try {
					const newContent = this.replace(replaceList);

					fs.writeFileSync(createfilePath, newContent);

					this.workCompleted(false, false);
				} catch (error) {
					errorDialog('错误', (error as Error).message);
				}
			};

			(this.fileInfo as MdFileInfo).imageInfo.forEach((item) => {
				if (item.fileExist && item.absolute) {
					const matchs = item.absolute.match(/.*\.([a-zA-Z]+)$/);
					let ext = matchs ? matchs[1] : 'png';

					const base64Str = fs.readFileSync(item.absolute).toString('base64');

					const base64URL = `data:image/${ext};base64,${base64Str}`;

					replaceList.push({
						target: item.target,
						substituted: base64URL,
						directReplace: true,
					});
				}
			});

			const fn = async () => {
				const imageInfo = (this.fileInfo as MdFileInfo).imageInfo;
				for (let i = 0; i < imageInfo.length; i++) {
					if (imageInfo[i].type === 'url') {
						const base64URL = await this.loadImage(imageInfo[i].target);
						if (base64URL) {
							replaceList.push({
								target: imageInfo[i].target,
								substituted: base64URL,
								directReplace: true,
							});
						}
					}
				}

				end();
			};

			if (obj.downloadOnlineImages) {
				fn();
			} else {
				end();
			}
		} else {
			let createDirPath = __path.addNumber(path.join(obj.outputPath, buildDirName), 'dir') as string; // 创建文件夹路径
			if (!createDirPath) return;
			const imagesSavePath = path.join(createDirPath, imagesDirName); // 图片保存目录

			const end = () => {
				try {
					const newContent = this.replace(replaceList);

					fs.writeFileSync(path.join(createDirPath, (this.fileInfo as MdFileInfo).fileName), newContent);

					this.workCompleted(false, false);
				} catch (error) {
					errorDialog('错误', (error as Error).message);
				}
			};

			let names = 1;

			// 处理本地图片
			(this.fileInfo as MdFileInfo).imageInfo.forEach((item) => {
				if (item.fileExist && item.absolute) {
					const replaceObj = {
						target: '',
						substituted: '',
					};

					const moveObj = {
						mode: 'copy' as MoveFileConfig['mode'],
						target: '',
						movePosition: '',
					};

					replaceObj.target = item.target;
					moveObj.target = item.absolute;

					const index = moveList.findIndex((t) => t.target === item.absolute);

					// 判断移动信息中是否已有
					if (index === -1) {
						const newFilename = item.absolute.replace(/.*(\.[a-zA-Z]+)$/, `${names++}$1`);

						replaceObj.substituted = imagesDirName + '/' + newFilename;

						moveObj.movePosition = path.join(createDirPath, imagesDirName, newFilename);

						moveList.push(moveObj);
					} else {
						replaceObj.substituted = imagesDirName + '/' + path.basename(moveList[index].movePosition);
					}

					replaceList.push(replaceObj);
				}
			});

			// 处理网络图片
			if (obj.downloadOnlineImages) {
				(this.fileInfo as MdFileInfo).imageInfo.forEach((item) => {
					if (item.type === 'url') {
						let filename = getURLFilename(item.target);
						let notExt = false;

						if (filename) {
							filename = filename.replace(/.*(\.[a-zA-Z]+)$/, `${names++}$1`);
						} else {
							filename = '' + names++;
							notExt = true;
						}

						const index = downloadInfo.findIndex((t) => t.url === item.target);

						if (index === -1) {
							downloadInfo.push({
								savePath: imagesSavePath,
								url: item.target,
								filename,
								notExt,
							});
						}

						replaceList.push({
							target: item.target,
							substituted: imagesDirName + '/' + (index === -1 ? filename : downloadInfo[index].filename),
						});
					}
				});
			}

			try {
				fs.mkdirSync(createDirPath); // 创建打包路径

				// 判断是否需要创建图片存在路径
				if (moveList.length > 0 || downloadInfo.length > 0) {
					fs.mkdirSync(imagesSavePath);
				}

				// 移动文件
				this.moveFile(moveList).then((result) => {
					result.forEach((item) => {
						const un: number[] = [];
						if (!item.result) {
							replaceList.forEach((t, i) => {
								if (path.basename(t.substituted) === path.basename(item.movePosition)) un.push(i);
							});

							un.forEach((t) => replaceList.splice(t, 1));
						}
					});

					// 下载图片
					if (downloadInfo.length > 0) {
						download(downloadInfo, this.sendMessage.bind(this), this.loadImageData).then((result2) => {
							result2.forEach((item) => {
								const un: number[] = [];
								if (!item.result) {
									replaceList.forEach((t, i) => {
										if (t.target === item.url) un.push(i);
									});

									un.forEach((t) => replaceList.splice(t, 1));
								}
							});

							end();
						});
					} else {
						end();
					}
				});
			} catch (error) {
				errorDialog('错误', (error as Error).message);
			}
		}
	}
}
